/*
 * Copyright (C) 2014 Lucid Wolf
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.lucidhex.viewer.mapimport;

import com.lucidhex.LucidWorld;
import com.lucidhex.hex.LucidCoord;
import com.lucidhex.hex.LucidIndex;
import com.lucidhex.hex.PlaneCoord;
import com.lucidhex.hex.LucidHex;
import com.lucidhex.hex.LucidHexType;
import com.lucidhex.viewer.ViewTransform;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;

/**
 *
 * @author Wolf
 */
public class MaptoHexImport extends javax.swing.JDialog {

    /**
     * Creates new form MaptoHexImport
     */
    BufferedImage img;
    LucidWorld world;
    LucidWorld testErf;
    Point pt1 = null;
    Point pt2 = null;
    LucidIndex index1 = null;
    LucidIndex index2 = null;
    ColorListModel hexChoiceByColor = new ColorListModel();
    ArrayList<Point> hexCentersOnImg = new ArrayList<>();
    public MaptoHexImport(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        testErf = new LucidWorld();
        viewPortal.setErf(testErf);
        
    }
    public void buildPictureView(LucidWorld aWorld, File f) {
        world = aWorld;
        hexChoiceByColor.setBaseWorld(world);
        try {
            img = ImageIO.read(f);
        } catch (IOException e) {
        }
        if (img == null) {
            return;
        }
        mapPicture.setImg(img);
        mapPicture.setMapImportFrame(this, world);
;
        repaint();
    }

    public void setBaseWorld(LucidWorld aWorld) {
        world = aWorld;
        hexChoiceByColor.setBaseWorld(world);
        
    }

    public void setCoordinates(Point pt1In, Point pt2In, String coord1, String coord2) {
        if(index1 == null && (coord1 == null || coord1.trim().isEmpty())){
            coord1 = JOptionPane.showInputDialog(this, "FirstPoint Coord", "Erf,Fate,Number or Erf,Number");
        }
        try {
            String[] split = coord1.split(",");
            int a = Integer.parseInt(split[0].trim());
            int c = Integer.parseInt(split[1].trim()); // dont use fate
            if (split.length == 3) {
                c = Integer.parseInt(split[2].trim());
            }
            index1 = new LucidIndex(a, c);
        } catch (Exception e){}        
        if(index2 == null && (coord2 == null || coord2.trim().isEmpty())){
            coord2 = JOptionPane.showInputDialog(this, "Second Point Coord", "Erf,Fate,Number or Erf,Number");
        }
        try {
            String[] split = coord2.split(",");
            int a = Integer.parseInt(split[0].trim());
            int c = Integer.parseInt(split[1].trim()); // dont use fate
            if (split.length == 3) {
                c = Integer.parseInt(split[2].trim());
            }
            index2 = new LucidIndex(a, c);
        } catch (Exception e){}
        if (index1 != null && pt1In != null) {
            pt1 = pt1In;
            location1.setText("["+pt1.x+","+pt1.y+"] ("+index1.toString()+")");
        }else{
            pt1 = null;
            index1 = null;
            location1.setText("Point 1 Not Set");
        }
        if (index2 != null && pt2In != null) {
            pt2 = pt2In;
            location2.setText("["+pt2.x+","+pt2.y+"] ("+index2.toString()+")");            
        }else{
            pt2 = null;
            index2 = null;
            location2.setText("Point 2 Not Set");
        }
        runComputations();
    }

    public void setHexImportColor(Color color, LucidHexType aHex) {
        hexChoiceByColor.put(color, aHex);
        runComputations();
    }

    private void runComputations() {
        //if(!rebuildButton.isSelected()){return;}
        if(pt1 == null || pt2 ==null || index1 == null || index2 ==null){return;}
        ViewTransform mit = new ViewTransform(index1, index2, pt1, pt2);
        theta.setText(""+(float)(mit.getTheta()/Math.PI*180));
        HashSet<LucidIndex> indexes = new HashSet<>();
        hexCentersOnImg = new ArrayList<>();
        // <>< Need to add check for really big pict to map ratios
        for (int i = 0; i < img.getWidth(); i++) {
            for (int j = 0; j < img.getHeight(); j++) {
                indexes.add(new LucidIndex(new LucidCoord(mit.reverseTransform(i, j))));
            }
        }
        for (LucidIndex ei : indexes) {
            PlaneCoord sc = new PlaneCoord(ei);
            int pixelLoc[] = mit.transformPoint(sc);
            hexCentersOnImg.add(new Point(pixelLoc[0],pixelLoc[1]));
            if (pixelLoc[0] > 0 && pixelLoc[0] < img.getWidth() && pixelLoc[1] > 0 && pixelLoc[1] < img.getHeight()) {
                int rbgValue = img.getRGB(pixelLoc[0], pixelLoc[1]);
                Color test = new Color(rbgValue);
                double minColorDist = Double.MAX_VALUE;
                LucidHexType type = null;
                for (Color color  : hexChoiceByColor.keySet()) {
                    double dist = colorDistance(test, color);
                    if (dist < minColorDist) {
                        minColorDist = dist;
                        type = hexChoiceByColor.getValue(color);
                    }
                }
                if (type != null) {
                        // have Hex type cast it and add to map
                        LucidHex ef = type.makeNewHex(testErf.getBoard());
                        testErf.getBoard().addHex(ei, ef);
                }
            }
        }
        // hexes added update view
        okButton.setEnabled(true);
        this.repaint();

    }
    public ArrayList<Point> getHexCentersAsPoints() {
        return hexCentersOnImg;
    }
    public static double colorDistance(Color c1, Color c2) {
        int red1 = c1.getRed();
        int red2 = c2.getRed();
        int rmean = (red1 + red2) >> 1;
        int r = red1 - red2;
        int g = c1.getGreen() - c2.getGreen();
        int b = c1.getBlue() - c2.getBlue();
        return Math.sqrt((((512 + rmean) * r * r) >> 8) + 4 * g * g + (((767 - rmean) * b * b) >> 8));
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        colorListModel1 = new com.lucidhex.viewer.mapimport.ColorListModel();
        rebuildButton = new javax.swing.JButton();
        location1 = new javax.swing.JLabel();
        location2 = new javax.swing.JLabel();
        theta = new javax.swing.JLabel();
        ModifyPoints = new javax.swing.JButton();
        okButton = new javax.swing.JButton();
        jSplitPane1 = new javax.swing.JSplitPane();
        mapPicture = new com.lucidhex.viewer.mapimport.MapPicture();
        viewPortal = new com.lucidhex.viewer.ViewPortal();
        jComboBox1 = new javax.swing.JComboBox();
        colorReset = new javax.swing.JButton();
        rebuildToggle = new javax.swing.JToggleButton();

        rebuildButton.setText("Rebuild");
        rebuildButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        rebuildButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        rebuildButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                rebuildButtonActionPerformed(evt);
            }
        });

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        location1.setText("lc1");

        location2.setText("lc2");

        theta.setText("theta");

        ModifyPoints.setText("Modify");
        ModifyPoints.setFocusable(false);
        ModifyPoints.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        ModifyPoints.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        ModifyPoints.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ModifyPointsActionPerformed(evt);
            }
        });

        okButton.setText("Import");
        okButton.setAlignmentX(1.0F);
        okButton.setEnabled(false);
        okButton.setFocusable(false);
        okButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        okButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        okButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                okButtonActionPerformed(evt);
            }
        });

        jSplitPane1.setDividerLocation(300);
        jSplitPane1.setResizeWeight(1.0);

        mapPicture.setPreferredSize(new java.awt.Dimension(500, 500));

        javax.swing.GroupLayout mapPictureLayout = new javax.swing.GroupLayout(mapPicture);
        mapPicture.setLayout(mapPictureLayout);
        mapPictureLayout.setHorizontalGroup(
            mapPictureLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 299, Short.MAX_VALUE)
        );
        mapPictureLayout.setVerticalGroup(
            mapPictureLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 375, Short.MAX_VALUE)
        );

        jSplitPane1.setLeftComponent(mapPicture);

        viewPortal.setPreferredSize(new java.awt.Dimension(500, 500));

        javax.swing.GroupLayout viewPortalLayout = new javax.swing.GroupLayout(viewPortal);
        viewPortal.setLayout(viewPortalLayout);
        viewPortalLayout.setHorizontalGroup(
            viewPortalLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 563, Short.MAX_VALUE)
        );
        viewPortalLayout.setVerticalGroup(
            viewPortalLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 375, Short.MAX_VALUE)
        );

        jSplitPane1.setRightComponent(viewPortal);

        jComboBox1.setModel(hexChoiceByColor);

        colorReset.setText("Reset");
        colorReset.setFocusable(false);
        colorReset.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        colorReset.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        colorReset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                colorResetActionPerformed(evt);
            }
        });

        rebuildToggle.setSelected(true);
        rebuildToggle.setText("ReBuild Model");
        rebuildToggle.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                rebuildToggleActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 869, Short.MAX_VALUE)
            .addGroup(layout.createSequentialGroup()
                .addComponent(ModifyPoints)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(location1, javax.swing.GroupLayout.PREFERRED_SIZE, 146, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(location2, javax.swing.GroupLayout.PREFERRED_SIZE, 147, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(theta, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(colorReset)
                .addGap(65, 65, 65)
                .addComponent(rebuildToggle)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(okButton))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 377, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(location1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(location2, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(theta, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(colorReset)
                    .addComponent(ModifyPoints)
                    .addComponent(okButton)
                    .addComponent(rebuildToggle)))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void ModifyPointsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ModifyPointsActionPerformed
        ModifyMapPictureImport mmpi = new ModifyMapPictureImport(this, true);
        mmpi.setHexImportDialog(this);
        mmpi.setVisible(true);
        this.repaint();

    }//GEN-LAST:event_ModifyPointsActionPerformed

    private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
        if (!testErf.getBoard().isEmpty()) {
            for (LucidHex eh : testErf.getBoard().getAvailbleHexes()) {
                LucidIndex ei = testErf.getBoard().getPosition(eh);
                world.getBoard().addHex(ei, eh);
            }
        }
        this.setVisible(false);
        this.dispose();
    }//GEN-LAST:event_okButtonActionPerformed

    private void rebuildButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rebuildButtonActionPerformed
        // TODO add your handling code here:
            runComputations();
    }//GEN-LAST:event_rebuildButtonActionPerformed

    private void colorResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_colorResetActionPerformed
        hexChoiceByColor.reset();
        testErf = new LucidWorld();
        viewPortal.setErf(testErf);
        runComputations();
    }//GEN-LAST:event_colorResetActionPerformed

    private void rebuildToggleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rebuildToggleActionPerformed
        // TODO add your handling code here:
            runComputations();
    }//GEN-LAST:event_rebuildToggleActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton ModifyPoints;
    private com.lucidhex.viewer.mapimport.ColorListModel colorListModel1;
    private javax.swing.JButton colorReset;
    private javax.swing.JComboBox jComboBox1;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JLabel location1;
    private javax.swing.JLabel location2;
    private com.lucidhex.viewer.mapimport.MapPicture mapPicture;
    private javax.swing.JButton okButton;
    private javax.swing.JButton rebuildButton;
    private javax.swing.JToggleButton rebuildToggle;
    private javax.swing.JLabel theta;
    private com.lucidhex.viewer.ViewPortal viewPortal;
    // End of variables declaration//GEN-END:variables

    Point getPoint1() {
        return pt1;
    }
    Point getPoint2() {
        return pt2;
    }

    public String getCoord1() {
        if(index1 == null){
            return "";
        }
        return index1.toString();
    }
    public String getCoord2() {
        if(index2 == null){
            return "";
        }
        return index2.toString();
    }



}
